#include <iostream>
#include <string>
#include <memory>

using namespace std;

/*
\ brief:  表达式
\ author: 清晨与猫鱼
*/
class Expression {
public:
    virtual bool interpret(string context) = 0;
};


/*
\ brief:  终端表达式
\ author: 清晨与猫鱼
*/
class TerminalExpression 
    : public Expression {
public:
    explicit TerminalExpression(string data)
        : data_(move(data)) {
    }

/*
\ brief:  翻译
\ author: 清晨与猫鱼
*/
    bool interpret(string context) {
       return context.find(data_) != string::npos;
    }
private:
    string data_;
};


/*
\ brief:  或表达式
\ author: 清晨与猫鱼
*/
class OrExpression 
    : public Expression {
public:
    explicit OrExpression(Expression* expr1, Expression* expr2)
        : expr1_(expr1), expr2_(expr2){
    }

    bool interpret(string context) {
        return expr1_->interpret(context) || expr2_->interpret(context);
    }

private:
    unique_ptr<Expression> expr1_;      
    unique_ptr<Expression> expr2_;
};


/*
\ brief:  与表达式
\ author: 清晨与猫鱼
*/
class AndExpression 
    : public Expression {
public:
    explicit AndExpression(Expression* expr1, Expression* expr2)
        : expr1_(expr1), expr2_(expr2){
    }

    bool interpret(string context) {
        return expr1_->interpret(context) && expr2_->interpret(context);
    }
private:
    unique_ptr<Expression> expr1_;
    unique_ptr<Expression> expr2_;
};


